﻿/***************************************************************
 * 开发人员：网魂小兵@http://www.mozlite.com
 * 
 * 目标标本：4.0.30319.239
 * 
 * 最后修改：2011/11/2 12:24:31
 * ************************************************************/
namespace Mozlite.Common
{
    using System;
    using System.Linq;
    using System.Text;
    using System.Collections.Generic;
    using System.Net.Mail;
    using System.Net;
    using System.Text.RegularExpressions;
    using Mozlite.Common.Configuration;
    using Mozlite.Web.UI;

    /// <summary>
    /// 邮件管理类。
    /// </summary>
    public class Mails
    {
        private Mails() { }
        /// <summary>
        /// 获取<see cref="T:System.Net.Mail.SmtpClient"/>实例对象。
        /// </summary>
        /// <returns>返回<see cref="T:System.Net.Mail.SmtpClient"/>实例对象。</returns>
        internal protected static SmtpClient GetClient()
        {
            SiteSettings settings = SiteSettings.Current;
            SmtpClient client = new SmtpClient(settings.SmtpHost, settings.SmtpPort);
            if (settings.UseNtlmCredentials)
            {
                client.Credentials = CredentialCache.DefaultNetworkCredentials;
                return client;
            }
            if (settings.RequiresLogin)
            {
                client.Credentials = new NetworkCredential(settings.SmtpUserName, settings.SmtpPassword);
            }
            return client;
        }
        /// <summary>
        /// 将字符串转义为HTML字符串。
        /// </summary>
        /// <param name="stringToFormat">字符串。</param>
        /// <returns>返回转义后的HTML字符串。</returns>
        public static string FormatHtmlAsPlainText(string stringToFormat)
        {
            if (stringToFormat == null || stringToFormat == string.Empty)
            {
                return "";
            }
            stringToFormat = Regex.Replace(stringToFormat, "\n", " ", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            stringToFormat = Regex.Replace(stringToFormat, @"</?(br|p|li|blockquote)(\s/)?>", "\n", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            stringToFormat = Regex.Replace(stringToFormat, "</?(\\w+)(\\s*\\w*\\s*=\\s*(\"[^\"]*\"|'[^']'|[^>]*))*|/?>", "", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            stringToFormat = stringToFormat.Replace("&nbsp;", " ");
            stringToFormat = stringToFormat.Replace("&lt;", "<");
            stringToFormat = stringToFormat.Replace("&gt;", ">");
            stringToFormat = stringToFormat.Replace("&amp;", "&");
            stringToFormat = stringToFormat.Replace("&quot;", "\"");
            return stringToFormat;
        }
        /// <summary>
        /// 将字符串换行和链接格式化为HTML格式。
        /// </summary>
        /// <param name="stringToFormat">字符串。</param>
        /// <returns>返回格式化后的字符串。</returns>
        public static string FormatPlainTextAsHtml(string stringToFormat)
        {
            if (stringToFormat == null || stringToFormat == string.Empty)
            {
                return "";
            }
            stringToFormat = Regex.Replace(stringToFormat, "\n", "<br />", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            stringToFormat = Regex.Replace(stringToFormat, @"(http|ftp|https):\/\/[\w]+(.[\w]+)([\w\-\.,@?^=%&:/~\+#\$]*[\w\-\@?^=%&/~\+#])?", "<a href=\"$0\">$0</a>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            return stringToFormat;
        }
        /// <summary>
        /// 创建用户后发送的电子邮件。
        /// </summary>
        /// <param name="user">用户实例对象。</param>
        /// <param name="password">明文密码字符串。</param>
        public static void UserCreated(User user, string password)
        {
            QueueUser(user, MailType.NewUserAccountCreated, password);
        }

        private static readonly Regex tokenRegex = new Regex("\\[([a-z0-9_.]+?)\\]", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline);

        private static string UserTokens(string input, User user, string password = null)
        {
            return tokenRegex.Replace(input, match =>
            {
                string key = match.Groups[1].Value;
                switch (key.ToLower())
                {
                    case "sitename":
                        return string.Format("{0}({1})", SiteSettings.Current.SiteName, SiteSettings.Current.SiteDomain);
                    case "username":
                        return user.UserName;
                    case "profileurl":
                        return CommonHelper.Combine("http://" + SiteSettings.Current.SiteDomain, "#");
                    case "now":
                        return user.Now.ToString(user.DateFormat);
                    case "password":
                        return password;
                    case "loginurl":
                        return CommonHelper.Combine("http://" + SiteSettings.Current.SiteDomain, CommonUrls.Logon);
                    case "activeurl":
                        return CommonHelper.Combine("http://" + SiteSettings.Current.SiteDomain, SiteUrls.GetActiveUser(user));
                }
#if DEBUG
                Logs.Debug(string.Format("Mail token({0})'s replacement is not found!", key), "email", EventID.Mail, "电子邮件");
#endif
                return null;
            });
        }

        private static void QueueUser(User user, MailType type, string password = null)
        {
            Mail email = GetMail(user.Language, type);
            if (email == null)
                return;
            email.ToAddresses = user.Email;
            email.Subject = UserTokens(email.Subject, user, password);
            email.Body = UserTokens(email.Body, user, password);
            email.Queue();
        }
        /// <summary>
        /// 激活用户。
        /// </summary>
        /// <param name="user">用户实例对象。</param>
        /// <param name="password">明文密码。</param>
        public static void UserActivate(User user, string password)
        {
            QueueUser(user, MailType.NewUserAccountActiving, password);
        }
        /// <summary>
        /// 重新设定密码。
        /// </summary>
        /// <param name="user">用户实例对象。</param>
        /// <param name="password">随机密码。</param>
        public static void UserCreateGeneratedPassword(User user, string password)
        {
            QueueUser(user, MailType.ForgottenPassword, password);
        }
        /// <summary>
        /// 用户等待验证。
        /// </summary>
        /// <param name="user">用户实例对象。</param>
        public static void UserAccountPending(User user)
        {
            QueueUser(user, MailType.NewUserAccountPending);
        }
        /// <summary>
        /// 获取资源Mail模板实例对象。
        /// </summary>
        /// <param name="language">语言。</param>
        /// <param name="emailType">电子邮件类型。</param>
        /// <returns>返回资源Mail模板实例对象。</returns>
        public static Mail GetMail(string language, MailType emailType)
        {
            Dictionary<MailType, Mail> emails = Caches.Get<Dictionary<MailType, Mail>>(string.Format("Mails::Language-{0}", language), Globals.MinuteSeconds, Globals.MinuteSeconds *3, () =>
                {
                    Dictionary<MailType, Mail> inner = new Dictionary<MailType, Mail>();
                    Globals.ForEach<MailType>(type =>
                    {
                        //inner.Add(type, new Mail(Resources.GetString(emailType, language)));
                    });
                    return inner;
                });
            Mail entry;
            if (emails != null && emails.TryGetValue(emailType, out entry))
                return entry;
            return null;
        }
        /// <summary>
        /// 抽取Mail队列中的邮件。
        /// </summary>
        /// <returns>返回抽取的邮件列表。</returns>
        public static Dictionary<Guid, Mail> DequeueMails()
        {
            return CommonDataProvider.Current.DequeueMails(SiteSettings.Current.EachDequeueSize);
        }
        /// <summary>
        /// 删除队列中的电子邮件。
        /// </summary>
        /// <param name="emailID">ID。</param>
        public static void DeleteQueuedMail(Guid emailID)
        {
            CommonDataProvider.Current.DeleteQueuedMail(emailID);
        }
        /// <summary>
        /// 将发送失败的对象插入到队列中。
        /// </summary>
        /// <param name="list">发送失败的电子邮件的ID列表。</param>
        /// <param name="failureInterval">几分钟后继续发送。</param>
        /// <param name="maxNumberOfTries">最大发送次数。</param>
        public static void QueueSendingFailure(List<Guid> list, int failureInterval, int maxNumberOfTries)
        {
            CommonDataProvider.Current.QueueSendingFailure(list, failureInterval, maxNumberOfTries);
        }
    }
}